package cn.fastoo.common.sampleframe;

import com.alibaba.fastjson.JSONObject;
import cn.fastoo.common.sampleframe.annotation.ColumnDefine;
import cn.fastoo.common.sampleframe.entity.BatchSql;
import cn.fastoo.common.sampleframe.search.Search;
import cn.fastoo.common.sampleframe.springside.Collections3;
import cn.fastoo.common.sampleframe.springside.SearchFilter;
import cn.fastoo.common.sampleframe.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.KeyHolder;

import javax.persistence.*;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.*;
import java.util.Date;


public class SqlUtils {


	public static String  SQL_PAGE =  	 		"SELECT #选择字段#"
									  + 		" FROM "
									  + 			" #表名# "
									  + 		" WHERE  "
									  + 			" 1=1 "
									  + 			" #查询限制条件# "
									  +				" #排序# "
									  + 		" limit #pageStart#,#pageSize# ";
	
	
	public static String SQL_QUERY = "SELECT #选择字段# FROM #表名# WHERE 1=1 #查询限制条件# #排序#";
	
	public static String SQL_INSERT = "INSERT INTO  #表名#  (#所有的列#) VALUES (#所有值#) ";
	
	public static String SQL_UPDATE = "UPDATE #表名# SET #列名称 =新值# WHERE 1=1 #主键关联条件# ";
	
	public static String SQL_DELETE = "DELETE FROM #表名# WHERE 1=1 #查询限制条件#";
	
	public static String SQL_COUNT =  "SELECT COUNT(*) FROM #表名# where 1=1 #查询限制条件#";


	
	@SuppressWarnings("rawtypes")
	public static String getPageSql(Search search, Class  clazz){
		PageRequest pageRequest = search.getPageRequest();
		List<String> idCondtions = new ArrayList<String>();
		JPAInfo jpaInfo = getJPAInfo(clazz);
		for (String id : jpaInfo.getIdColumnList()) {
			idCondtions.add(String.format(" a.%s = back.%s ", id,id));
		}

		String pageSql = SQL_PAGE.replace("#表名#", " "+jpaInfo.getTable()+" ")
								 .replace("#查询限制条件#", search!=null?getConditionSql(search, clazz):"")
								 .replace("#排序#", getSortSql(search,clazz))
								 .replace("#选择字段#", search!=null?getSelectSql(search,clazz):"*")
								 .replace("#pageStart#", String.valueOf(pageRequest.getOffset()))
							     .replace("#pageSize#",String.valueOf(pageRequest.getPageSize()));
								 //.replace("#pageEnd#",String.valueOf(pageRequest.getOffset()+pageRequest.getPageSize()));

		return pageSql;
	}

	public static String getSortSql(Search search,Class clazz){
		final JPAInfo jpaInfo = getJPAInfo(clazz);
		final StringBuffer sort = new StringBuffer();
		if(search!=null && search.getSort()!=null){
			sort.append(" ORDER BY ");
            Iterator<Order> orderIterator = search.getSort().iterator();
            while (orderIterator.hasNext()){
                Order t = orderIterator.next();
                sort.append(String.format(" %s %s ",jpaInfo.getFieldColumnMap().get(t.getProperty()),t.getDirection().name()));
            }
		}
		if(search.getPageRequest()!=null){
			Sort pageSort = search.getPageRequest().getSort();
			if(pageSort!=null){
				sort.append(" ORDER BY ");
                Iterator<Order> orderIterator = pageSort.iterator();
                while (orderIterator.hasNext()){
                    Order t = orderIterator.next();
                    sort.append(String.format(" %s  %s ",jpaInfo.getFieldColumnMap().get(t.getProperty()),t.getDirection().name()));
                }
			}
		}
		 
		return sort.toString();
	}
	@SuppressWarnings("rawtypes")
	public static String getQuerySql(Search search,Class clazz){
		JPAInfo jpaInfo = getJPAInfo(clazz);
		String sql = SQL_QUERY.replace("#表名#", jpaInfo.getTable())
							  .replace("#排序#",  getSortSql(search,clazz))
							  .replace("#查询限制条件#", search!=null?getConditionSql(search, clazz):"")
							  .replace("#选择字段#", search!=null?getSelectSql(search,clazz):"*");
		if(search.getLimit()!=null){
			sql += String.format(" LIMIT 0,%s ",search.getLimit());
		}
		if(search.getForUpdate()){
			sql += String.format(" for update ");
		}
		return sql;
	}
	public static String getSearchDeleteSql(Search search,Class clazz) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		JPAInfo jpaInfo = getJPAInfo(clazz);
		String sql = SQL_DELETE.replace("#表名#", jpaInfo.getTable())
				.replace("#查询限制条件#", search!=null?getConditionSql(search, clazz):"");

		return sql;
	}
	
	 
	@SuppressWarnings("rawtypes")
	public static String getCountSql(Search search,Class clazz){
		JPAInfo jpaInfo = getJPAInfo(clazz);
		String sql = SQL_COUNT.replace("#表名#", jpaInfo.getTable()) 
							  .replace("#查询限制条件#", search!=null?getConditionSql(search, clazz):"");

		return sql;
	}
	
	@SuppressWarnings("rawtypes")
	public static String getConditionSql(final Search search,final Class clazz){
		StringBuffer result = new StringBuffer();
		for (SearchFilter t:search.values()) {
			result.append(String.format(" and  %s ",getCondtion(t,clazz)));
		}
		if(Collections3.isNotEmpty(search.getOrCore())){
			result.append(String.format(" and ( %s ) ",getCondtion(search.getOrCore(),clazz))) ;
		}
		return result.toString();
	}
	private static String getSelectSql(Search search, Class clazz) {
		if(Collections3.isEmpty(search.getSelect())){
			return "*";
		}
		List<String> sqlList = new ArrayList<String>();
		for (String select : search.getSelect()) {
			if(select.startsWith("jpa:")){
				select = select.replace("jpa:", "");
				Map<String, String> fieldColumn  =  getJPAInfo(clazz).getFieldColumnMap() ;
				for (String key :fieldColumn.keySet()) {
					select = select.replace(key, fieldColumn.get(key));
				} 
			}	 
				sqlList.add(select);
		}
		 
		 
		return "* ," + StringUtils.join(sqlList,",");
	}
	
	@SuppressWarnings("rawtypes")
	private static String getCondtion(List<Search> searchs,Class clazz){
		List<String> orStrs = new ArrayList<String>();
		for (Search search : searchs) {
			orStrs.add(String.format("( 1 = 1 %s )", getConditionSql(search,clazz)));
		} 
		return StringUtils.join(orStrs," or ");
	}
	@SuppressWarnings("rawtypes")
	private static String getCondtion(SearchFilter t, Class clazz){
		String operatorStr = null;
		switch (t.operator) {
		case EQ:
			operatorStr = " = ";
			break;
		case LIKE:
			StringBuilder value = new StringBuilder();
			value.append(" ");
			value.append(getColumnName(t.fieldName, clazz));
			value.append(" like '%");
			value.append(t.value.toString());
			value.append("%' ");
			return value.toString();
		case GT:
			operatorStr = " > ";
			break;
		case LT:
			operatorStr = " < ";
			break;
		case GTE:
			operatorStr = " >= ";
			break;
		case LTE:
			operatorStr = " <= ";
			break;
		case NEQ:
			operatorStr = " <> ";
			break;
		case IN:
			operatorStr = " in ";
			break;
		case NOTIN:
			operatorStr = " not in ";
			break;
		case SELF:
			return String.format(" (%s) ", t.value.toString());
		default:
			break;
		}
		Class fieldClazz =  getJPAInfo(clazz).getFieldPDMap().get(t.fieldName).getReadMethod().getReturnType();
		return String.format(" %s %s %s", getColumnName(t.fieldName, clazz),operatorStr,getSqlValue(fieldClazz, t.value));
	}
 
	
	public static String getIdCondition(Object object) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		JPAInfo jpaInfo = getJPAInfo(object.getClass());
		List<String> idContion = new ArrayList<String>();
		for (String field : jpaInfo.getFieldColumnMap().keySet()) {
			String columnName = jpaInfo.getFieldColumnMap().get(field);
			if(jpaInfo.getIdColumnList().contains(columnName)){
				Method readMethod = jpaInfo.getFieldPDMap().get(field).getReadMethod();
				Object columnValue = readMethod.invoke(object);
				if(columnValue==null){
					return null;
				}
				String valueStr = getSqlValue(readMethod.getReturnType(),columnValue);
				idContion.add(String.format(" %s=%s ", columnName,valueStr));
			}
		}
		return StringUtils.join(idContion," and ");
	}
	public static String getDeleteSql(Object object) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		JPAInfo jpaInfo = getJPAInfo(object.getClass());
		//"DELETE FROM #表名# WHERE 1=1 #查询限制条件#";
		String idCondition = getIdCondition(object);
		if(StringUtils.isBlank(idCondition)){
			throw new IllegalArgumentException("JPA @ID value must not be null!");
		}
		return SQL_DELETE.replace("#表名#", jpaInfo.getTable()).replace("#查询限制条件#", " and "+idCondition);
	}

	
	 
	 
	
	private static String getSqlValue(Class fieldClazz,Object value){



		if(value==null){
			return null;
		}
		String valueStr = value.toString();
		if(fieldClazz.equals(Boolean.class)){
			return Boolean.valueOf(value.toString())?"1":"0";
		}
		if(value instanceof Date){
			return String.format("'%s'", DateUtils.formatDate((Date)value, "yyyy-MM-dd HH:mm:ss"));
		}
		if(value instanceof String || value instanceof JSONObject){
			return String.format("'%s'", value.toString());
		}
		if(value instanceof List){
			@SuppressWarnings("unchecked")
			List<Object> valueList = (List<Object>) value;
			if(valueList.get(0) instanceof String){
				List<String> newStr = new ArrayList<String>();
				for (Object t:valueList) {
					newStr.add(String.format("'%s'", t.toString()));
				}
				return String.format(" (%s) ", StringUtils.join(newStr,","));
			}
			if(valueList.get(0) instanceof Long){
				return String.format(" (%s) ", StringUtils.join(valueList,","));
			}
		}
		if(value instanceof String[]){
			String[] values = (String[]) value;
			List<String> newValueStr = new ArrayList<String>();
			for (String v : values) {
				newValueStr.add(getSqlValue(fieldClazz,v));
			}
			return String.format(" (%s) ", StringUtils.join(newValueStr, ",")); 
		}
		return valueStr;
	}
	
	private static Object getValue(Class valueClass,Object value){
		if(value==null){
			if(valueClass.equals(String.class) ){
				return "";
			}

			if(valueClass.equals(Integer.class)||valueClass.equals(Long.class)){
				return String.valueOf(0);
			}
			return null;
		}
		String valueStr = value.toString();
		//TODO
		if(value instanceof Date){
			return DateUtils.formatDate((Date)value, "yyyy-MM-dd HH:mm:ss");
		}
		if(value instanceof JSONObject){
			return ((JSONObject) value).toJSONString();
		}
		if(value instanceof Boolean){
			return value;
		}
		return valueStr;
	}
	
	
	public static PreparedStatementCreator getInsertPSC(Object object) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		if(object==null)return null;
		JPAInfo jpaInfo = getJPAInfo(object.getClass());
		List<String> columnNames = new ArrayList<String>();
		final List<Object> values = new ArrayList<Object>();
		List<String> size = new ArrayList<String>();
		for (String field : jpaInfo.getFieldColumnMap().keySet()) {
			String columnName = jpaInfo.getFieldColumnMap().get(field);
			Method readMethod = jpaInfo.getFieldPDMap().get(field).getReadMethod();
			Object columnValue =  readMethod.invoke(object);
			//判断是否为ID?
			if(jpaInfo.getIdColumnList().contains(columnName)){
				if(columnValue==null){
					continue;
				}
			}
			if(jpaInfo.getFieldColumnAnnotationMap().get(field).insertable()==false){
				continue;
			}
			columnValue = getValue(readMethod.getReturnType(),columnValue);
			if(columnValue==null){
				continue;
			}
			size.add("?");
			columnNames.add(columnName);
			values.add(columnValue);
		}

		final String sql = SQL_INSERT.replace("#表名#", jpaInfo.getTable()).replace("#所有的列#", StringUtils.join(columnNames, ",")).replace("#所有值#", StringUtils.join(size,","));

		PreparedStatementCreator psc = new PreparedStatementCreator() {
			@Override
			public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
				 PreparedStatement ps = con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
				 for(int i=1;i<=values.size();i++){
				 	Object obj = values.get(i-1);
				 	if(obj==null){
				 		ps.setString(i,null);
					}else{
						ps.setObject(i, obj);
					}

                } 
				return ps;
			}
		}; 
		return psc;
	}

	public static BatchSql getBatchInsertSql(final Object objectsList) throws InvocationTargetException, IllegalAccessException {
		final List<Object> objects = (List<Object>) objectsList;
		if(Collections3.isEmpty(objects))return null;

		BatchSql batchSql = new BatchSql();

		Object object = objects.get(0);

		JPAInfo jpaInfo = getJPAInfo(object.getClass());
		List<String> columnNames = new ArrayList<String>();
		final List<List<Object>> values = new ArrayList<List<Object>>();
		//初始化 值列表
		int i =0 ;
		for(;i<objects.size();i++){
			values.add(new LinkedList<Object>());
		}

		List<String> size = new ArrayList<String>();
		for (String field : jpaInfo.getFieldColumnMap().keySet()) {
			String columnName = jpaInfo.getFieldColumnMap().get(field);
			Method readMethod = jpaInfo.getFieldPDMap().get(field).getReadMethod();

			Object columnValue =  readMethod.invoke(object);

			//判断是否为ID?
			if(jpaInfo.getIdColumnList().contains(columnName)){
				if(columnValue==null){
					continue;
				}
			}
			if(jpaInfo.getFieldColumnAnnotationMap().get(field).insertable()==false){
				continue;
			}
			size.add("?");
			columnNames.add(columnName);

			i =0 ;
			Object cv = null;
			for(;i<objects.size();i++){
				cv =  readMethod.invoke(objects.get(i));
				values.get(i).add(getValue(readMethod.getReturnType(),cv));
			}
		}

		final String sql = SQL_INSERT.replace("#表名#", jpaInfo.getTable()).replace("#所有的列#", StringUtils.join(columnNames, ",")).replace("#所有值#", StringUtils.join(size,","));

		batchSql.setSql(sql);

		BatchPreparedStatementSetter psc = new BatchPreparedStatementSetter() {
			@Override
			public void setValues(PreparedStatement ps, int i) throws SQLException {
				List<Object> value = values.get(i);
				for(int j=1;j<=value.size();j++){
					ps.setObject(j, value.get(j-1) );
				}
			}

			@Override
			public int getBatchSize() {
				return objects.size();
			}
		};

		batchSql.setBpss(psc);

		return batchSql;
	}

	
	public static PreparedStatementCreator getUpdateSql(Object object) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		if(object==null)return null;
		
		JPAInfo jpaInfo = getJPAInfo(object.getClass());
		String idCondition = getIdCondition(object);
		if(StringUtils.isBlank(idCondition)){
			throw new IllegalArgumentException("JPA @ID value must not be null!");
		}
		List<String> setStrs = new ArrayList<String>();
		final List<Object> values = new ArrayList<Object>();
		for (String field : jpaInfo.getFieldColumnMap().keySet()) {
			String columnName = jpaInfo.getFieldColumnMap().get(field);
			Method readMethod = jpaInfo.getFieldPDMap().get(field).getReadMethod();
			Object columnValue = readMethod.invoke(object);
			if(jpaInfo.getIdColumnList().contains(columnName) && !"version".equals(columnName)){
				continue;
			}
			if(jpaInfo.getFieldColumnAnnotationMap().get(field).updatable()==false){
				continue;
			}
			if("version".equals(columnName)){
				columnValue = Integer.valueOf(columnValue.toString())+1;
			}
			values.add(getValue(readMethod.getReturnType(),columnValue));
			setStrs.add(String.format(" %s=%s ",columnName,"?"));
		}
		final String sql = SQL_UPDATE.replace("#表名#", jpaInfo.getTable()).replace("#列名称 =新值#", StringUtils.join(setStrs, ",")).replace("#主键关联条件#"," and "+ idCondition );

		PreparedStatementCreator psc = new PreparedStatementCreator() {
			@Override
			public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
				 PreparedStatement ps = con.prepareStatement(sql);
				 for(int i=1;i<=values.size();i++){
            	   ps.setObject(i, values.get(i-1));
                } 
				return ps;
			}
		}; 
		
		return psc;
	}
	
	//TODO other class
	
	@SuppressWarnings("rawtypes")
	private static Map<Class, JPAInfo> jpaMap = new HashMap<Class, JPAInfo>();
	public static class JPAInfo  {
		private String table;
		private List<String> idColumnList = null;
		private Map<String, String> fieldColumnMap = null;
		private Map<String,String> fieldColumnDefineMap = null;
		private Map<String, PropertyDescriptor> fieldPDMap = null;
		private RowMapper<Object>  rowMapper = null;
		
		private Map<String,Column> fieldColumnAnnotationMap = new HashMap<String,Column>();

		private Map<String,ColumnDefine> fieldColumnDefineAnnotationMap = new HashMap<String, ColumnDefine>();
		
		private Map<String, GeneratedValue> fieldGeneratedValue = new HashMap<String,GeneratedValue>();
		
		public JPAInfo (String table,List<String> idColumnList,Map<String, String> fieldColumnMap,Map<String, PropertyDescriptor> fieldPDMap){
			this.table = table;
			this.setIdColumnList(idColumnList);
			this.setFieldColumnMap(fieldColumnMap);
			this.setFieldPDMap(fieldPDMap);
		}

		public List<String> getIdColumnList() {
			return idColumnList;
		}

		public void setIdColumnList(List<String> idColumnList) {
			
			this.idColumnList = idColumnList;
		}

		public String getTable() {
			return table;
		}

		public Map<String, String> getFieldColumnMap() {
			return fieldColumnMap;
		}

		public void setFieldColumnMap(Map<String, String> fieldColumnMap) {
			this.fieldColumnMap = fieldColumnMap;
		}

		public Map<String, PropertyDescriptor> getFieldPDMap() {
			return fieldPDMap;
		}

		public void setFieldPDMap(Map<String, PropertyDescriptor> fieldPDMap) {
			this.fieldPDMap = fieldPDMap;
		}

		public RowMapper getRowMapper() {
			return rowMapper;
		}

		public void setRowMapper(RowMapper rowMapper) {
			this.rowMapper = rowMapper;
		}

		 

		public Map<String,Column> getFieldColumnAnnotationMap() {
			return fieldColumnAnnotationMap;
		}

		public void setFieldColumnAnnotationMap(Map<String,Column> fieldColumnAnnotationMap) {
			this.fieldColumnAnnotationMap = fieldColumnAnnotationMap;
		}

		public Map<String, GeneratedValue> getFieldGeneratedValue() {
			return fieldGeneratedValue;
		}

		public void setFieldGeneratedValue(Map<String, GeneratedValue> fieldGeneratedValue) {
			this.fieldGeneratedValue = fieldGeneratedValue;
		}


		public Map<String, ColumnDefine> getFieldColumnDefineAnnotationMap() {
			return fieldColumnDefineAnnotationMap;
		}

		public void setFieldColumnDefineAnnotationMap(Map<String, ColumnDefine> fieldColumnDefineAnnotationMap) {
			this.fieldColumnDefineAnnotationMap = fieldColumnDefineAnnotationMap;
		}

		public Map<String, String> getFieldColumnDefineMap() {
			return fieldColumnDefineMap;
		}

		public void setFieldColumnDefineMap(Map<String, String> fieldColumnDefineMap) {
			this.fieldColumnDefineMap = fieldColumnDefineMap;
		}
	}
	
	@SuppressWarnings("rawtypes")
	private static String getColumnName(String fieldName,Class clazz){
		return getJPAInfo(clazz).getFieldColumnMap().get(fieldName);
	}
	@SuppressWarnings("rawtypes")
	public  static  JPAInfo getJPAInfo(Class clazz){
		if(!jpaMap.containsKey(clazz)){
			return getAndUpdateJPAInfo(clazz);
		}
		return jpaMap.get(clazz);
	}
	public static <T> T filledGeneratedField(T t,KeyHolder keyHolder) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		JPAInfo jpaInfo = getAndUpdateJPAInfo(t.getClass());
		Map<String, GeneratedValue> generatedValue = jpaInfo.getFieldGeneratedValue();
		int i = 0;
		for (String filed : generatedValue.keySet()) {
			if(generatedValue.get(filed).strategy().equals(GenerationType.AUTO)){
				Object value = keyHolder.getKeyList().get(0).get("GENERATED_KEY");
				PropertyDescriptor pd = jpaInfo.getFieldPDMap().get(filed);
				Class propClass =  pd.getPropertyType();
				if(propClass.equals(Long.class)){
					pd.getWriteMethod().invoke(t,Long.valueOf(value.toString()));
				}
				i++;
			}
		} 
		return t;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private  static synchronized   JPAInfo getAndUpdateJPAInfo(final Class clazz){
		if(jpaMap.containsKey(clazz)){
			return jpaMap.get(clazz);
		}
		JPAInfo result = null;
		String table  = ((Table) clazz.getAnnotation(Table.class)).name();
		
		PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(clazz);
		final Map<String, PropertyDescriptor > fieldPDMap = new HashMap<String, PropertyDescriptor >();
		for (PropertyDescriptor pd : pds) {
			fieldPDMap.put(pd.getName(), pd);
		}
		List<Field> fields = new ArrayList<Field>();
		Field[] fs =clazz.getDeclaredFields();
		for (Field f:fs) {
			fields.add(f);
		}
		Class supClazz = clazz.getSuperclass();
		Field[] superFields = clazz.getSuperclass().getDeclaredFields();
		for (Field f:superFields) {
			fields.add(f);
		}
		List<String> idColumnList = new ArrayList<String>();
		final Map<String, String> filedColumnMap = new HashMap<String,String>();
		final Map<String, String> filedColumnDefineMap = new HashMap<String,String>();
		Map<String , Column> columnAnno = new HashMap<String , Column>(); 
		Map<String, GeneratedValue> fieldGeneratedValue = new HashMap<String, GeneratedValue>();
		Map<String, ColumnDefine> fieldColumnDefine = new HashMap<String, ColumnDefine>();

		for (Field f : fields) {
				final Column column = f.getAnnotation(Column.class);
				final Id id = f.getAnnotation(Id.class);
				final GeneratedValue generatedValue = f.getAnnotation(GeneratedValue.class);
				final ColumnDefine columnDefine = f.getAnnotation(ColumnDefine.class);
				String columnName = null;
				//columnDefine==null
				if(columnDefine!=null){
					fieldColumnDefine.put(f.getName(),columnDefine);
					filedColumnDefineMap.put(f.getName(),columnDefine.selectColumn());
				}
				if(column==null ){
					continue;
				}
				if(StringUtils.isBlank(column.name())){
					columnName = f.getName();
				}else{
					columnName = column.name();
				}
				if(generatedValue!=null){
					fieldGeneratedValue.put(f.getName(), generatedValue);
				}

				if(id!=null){
					idColumnList.add(columnName);
				}
				filedColumnMap.put(f.getName(), columnName);
				columnAnno.put(f.getName(), column);
		}
		
		result = new JPAInfo(table,idColumnList, filedColumnMap,fieldPDMap);
		result.setFieldColumnAnnotationMap(columnAnno);
		result.setFieldGeneratedValue(fieldGeneratedValue);
		result.setFieldColumnDefineAnnotationMap(fieldColumnDefine);
		result.setRowMapper(new RowMapper<Object>() {
			@Override
			public Object mapRow(ResultSet rs, int rowNum)   {
				Object obj = null;
				try {
					obj = clazz.newInstance();
					Map<String,String> fieldMap = new HashMap<String,String>();
					fieldMap.putAll(filedColumnMap);
					fieldMap.putAll(filedColumnDefineMap);
					for (String  field :  fieldMap.keySet() ) {
						PropertyDescriptor pd = fieldPDMap.get(field);
						if(pd==null){
							throw new IllegalAccessError(String.format("%s   may be no set get method", field));
						}
						//拿到column的列值
						Class propClass = pd.getPropertyType();
						String fieldColumnName = fieldMap.get(field).trim();
						Object value = null;
						boolean find = false;
						for(int i =0 ;i<rs.getMetaData().getColumnCount();i++){
							if(rs.getMetaData().getColumnLabel(i+1).equals(fieldColumnName)){
								find = true;
								break;
							}
						}
						if(!find){
							continue;
						}
						value = getResultSetValue(rs,propClass,fieldColumnName);
						//约定注入
						pd.getWriteMethod().invoke(obj, value);
					}
				} catch (Exception e ) {
					e.printStackTrace();
					throw new RuntimeException(e.getMessage());
				}
				return obj;
			}
		});
		
		jpaMap.put(clazz, result);
		return result;
	}

	public static Object getResultSetValue(ResultSet rs,Class propClass,String fieldColumnName) throws SQLException {
		Object value = null;
		if(propClass.equals(String.class)){
			value = rs.getString(fieldColumnName);
		}else if(propClass.equals(Byte.class)){
			value = rs.getByte(fieldColumnName);
		}else if(propClass.equals(Long.class)){
			value = rs.getLong(fieldColumnName);
		}else if(propClass.equals(Integer.class)){
			value = rs.getInt(fieldColumnName);
		}else if(propClass.equals(Date.class)){
			value = rs.getTimestamp(fieldColumnName);
		}else if(propClass.equals(Float.class)){
			value = rs.getFloat(fieldColumnName);
		}else if(propClass.equals(Double.class)){
			value = rs.getDouble(fieldColumnName);
		}else if(propClass.equals(JSONObject.class)){
			value = JSONObject.parseObject(rs.getString(fieldColumnName));
		}else if(propClass.equals(Boolean.class)){
			value = rs.getBoolean(fieldColumnName);
		}
		return value;
	}



	
	public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//System.out.println(getColumnName("id", UserBaseInfo.class));
//		getJPAInfo(UserBaseInfo.class);
//		System.out.println(getConditionSql(new search().addSearchFilter("EQ_id", 1).addSearchFilter("EQ_loginName", "xdp"),  UserBaseInfo.class));
//		System.out.println(getQuerySql(new search().addSort(new Sort(Direction.DESC, "id")),UserBaseInfo.class));
//		UserBaseInfo u = new UserBaseInfo();
//		u.setId(1013L);
//		u.setLoginName("ttt");
//		System.out.println(getInsertSql(u));
//		System.out.println(getUpdateSql(u));
//		System.out.println(getSaveSql(u));
//		System.out.println(getDeleteSql(u));
		
	}
	
}
